import { effect, track, trigger, ITERATE_KEY } from "./index.js";

// 5.7.1数组索引与length
function createReactive(target, isShallow = false, isReadonly = false) {
  return new Proxy(target, {
    get(target, key, receiver) {
      if (key === "raw") {
        return target;
      }
      if (!isReadonly) {
        track(target, key);
      }
      const res = Reflect.get(target, key, receiver);
      if (isShallow) return res;
      if (typeof res === "object" && res !== null) {
        return isReadonly ? readonly(res) : reactive(res);
      }
      return res;
    },
    set(target, key, val, receiver) {
      if (isReadonly) {
        console.warn(`属性${key}是只读的`);
        return true;
      }
      console.log("set==", key, val);
      const oldVal = target[key];
      // 【1】如果被代理的目标是数组，检测被设置的索引值是否小于数组长度
      const type = Array.isArray(target)
        ? Number(key) < target.length
          ? "SET"
          : "ADD"
        : Object.prototype.hasOwnProperty.call(target, key)
        ? "SET"
        : "ADD";
      const res = Reflect.set(target, key, val, receiver);

      if (target === receiver.raw) {
        // console.log(" receiver 就是 target 的代理对象");
        if (oldVal !== val && (oldVal === oldVal || val === val)) {
          trigger(target, key, type, val);
        }
      }

      return res;
    },
    deleteProperty(target, key) {
      if (isReadonly) {
        console.warn(`属性${key}是只读的`);
        return true;
      }
      const hadKey = Object.prototype.hasOwnProperty.call(target, key);
      const res = Reflect.deleteProperty(target, key);
      if (res && hadKey) {
        trigger(target, key, "DELETE");
      }
      return res;
    },
    has(target, key) {
      return Reflect.has(target, key);
    },
    ownKeys(target, key) {
      track(target, ITERATE_KEY);
      return Reflect.ownKeys(target);
    },
  });
}
function reactive(target) {
  return createReactive(target);
}

const arr = reactive(["reactive1", "reactive2", "reactive3"]);
effect(() => {
  //   console.log("effect==", arr[0]);
  //   console.log("effect==", arr.length);
  // 访问数组的第 0 个元素
  console.log("effect==", arr[1]);
});
// arr[0] = "bar";
// arr[1] = "bar";
// 将数组的长度修改为 0，导致第 0 个元素被删除，因此应该触发响应
arr.length = 1;
